﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ComunesMGI.DataTypes;
using ComunesMGI.Enum;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace MGI.AccesoDatos
{
    class SharepointProxy: ISharepoint
    {

        #region ISharepoint Members

        /// <summary>
        /// Dado los títulos de los campos y otra información traida del xml 
        /// de configuración, se retorna una lista con información mas completa 
        /// (incluyendo la anterior) acerca de los campos, traida del sitio 
        /// sharepoint indicado por cliente-sistema.
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <param name="tipoLista"></param>
        /// <param name="nomCampos"></param>
        /// <returns>List<DataCampo></returns>
        public List<DataCampo> getCampos(DataCliente cliente, DataSistema sistema,Lista tipoLista,List<DataCampo> nomCampos)
        {
            SPSite mySite = new SPSite(sistema.Sitio);
            SPWeb myWeb = mySite.OpenWeb();
            
            SPList spLista;
            switch (tipoLista)
            {
                case Lista.Incidentes:
                    spLista = myWeb.Lists["Incidentes"];
                    break;
                case Lista.Tareas:
                    spLista = myWeb.Lists["Tareas"];
                    break;
                default:
                    spLista = myWeb.Lists["Incidentes"];
                    break;
            }
            List<DataCampo> campos = new List<DataCampo>();
            foreach (DataCampo dataCampo in nomCampos)
            {
                SPField spField = spLista.Fields[dataCampo.Titulo];
                CampoSharepoint tipoCampo = spTypeToCampoSharepoint(spField.TypeAsString);
                string tituloCampo =    spField.Title;
                string internalCampo =  spField.InternalName;
                int largoCampo =        System.Convert.ToInt32(spField.DisplaySize);
                bool requeridoCampo =   spField.Required;
                string defaultCampo =   spField.DefaultValue;
                
                DataCampo dataCampo2 = new DataCampo(tipoCampo,tituloCampo,defaultCampo,requeridoCampo, null);
                dataCampo2.ParteMail = dataCampo.ParteMail;
                
                switch (tipoCampo)
                {
                    case CampoSharepoint.Choice :
                        List<string> cadaChoice = new List<string>();
                        foreach (string choice in ((SPFieldChoice)spField).Choices )
                        {
                            cadaChoice.Add(choice);
                        }
                        dataCampo2.Opciones = cadaChoice;
                        break;
                    default:
                        break;
                }
                campos.Add(dataCampo2);        
            }
            return campos;            
        }


        








        /// <summary>
        /// Alta de incidente en sharepoint
        /// </summary>
        /// <param name="sistema"></param>
        public DataAltaIncidente addIncidente(DataSistema sistema) 
        {
            SPSite mySite = new SPSite(sistema.Sitio);
            SPWeb myWeb = mySite.OpenWeb();
            SPList spLista = myWeb.Lists["Incidentes"];
            DataAltaIncidente altaIncidente = Impactar(myWeb, spLista, sistema.Campos);
            myWeb.Close();
            mySite.Close();
            return altaIncidente;

        }


       

        /// <summary>
        /// Retorna información de todos los incidentes en el sitio 
        /// del cliente-sistema
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <returns>List<DataIncidente></returns>
        public List<DataIncidente> getIncidentes(DataCliente cliente, DataSistema sistema) 
        {
            SPSite mySite = new SPSite(sistema.Sitio);
            SPWeb myWeb = mySite.OpenWeb();
            SPList spLista = myWeb.Lists["Incidentes"];
            List<DataIncidente> listaDataIncidente = new List<DataIncidente> (); 
            string tituloIncidente;
            string idIncidente;
            foreach (SPListItem spItem in spLista.Items) 
            {
                idIncidente  =  spItem["ID"].ToString();
                if (spItem["Título"] != null)
                {
                    tituloIncidente = spItem["Título"].ToString();
                }
                else 
                {
                    tituloIncidente = "-no hay dato-";
                }
                DataIncidente dataIncidente = new DataIncidente(idIncidente, tituloIncidente);
                listaDataIncidente.Add(dataIncidente);
            }
            myWeb.Close();
            mySite.Close();
            return listaDataIncidente;
        }

        /// <summary>
        /// Retorna las tareas en el sitio del sistema y cliente indicados 
        /// que esten asociadas al incidente indicado
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <param name="incidente"></param>
        /// <returns>List<DataTarea></returns>
        public List<DataTarea> getTareas (DataCliente cliente, DataSistema sistema, DataIncidente incidente)
        {
            SPSite mySite = new SPSite(sistema.Sitio);
            SPWeb myWeb = mySite.OpenWeb();
            SPList spLista = myWeb.Lists["Tareas"];
            List<DataTarea> listaDataTarea  = new List<DataTarea>();
            foreach (SPListItem spItem in spLista.Items)
            {
                if (spItem["IDOriginal"].ToString() == incidente.IdIncidente)
                {
                    DataTarea dataTarea = new DataTarea(spItem["ID"].ToString(), spItem["Título"].ToString());
                    listaDataTarea.Add(dataTarea);
                }
            }
            myWeb.Close();
            mySite.Close();
            return listaDataTarea;
        }

        /// <summary>
        /// Dado un incidente de determinado sistema, una tarea y un usuario,
        /// se asigna la tarea al usuario y se asocia la misma al incidente
        /// </summary>
        /// <param name="sistema"></param>
        /// <param name="incidente"></param>
        /// <param name="tarea"></param>
        /// <param name="usuario"></param>
        /// <returns>bool</returns>
        public bool asignarResponsable(DataSistema sistema, DataIncidente incidente, DataTarea tarea, DataUsuario usuario)
        {
            SPSite mySite = new SPSite(sistema.Sitio);
            SPWeb myWeb = mySite.OpenWeb();
            SPList spLista = myWeb.Lists["Tareas"];
            SPListItem spItem = spLista.Items.GetItemById(System.Convert.ToInt32(tarea.IdTarea));

            bool resultado = false;
            if (SPUtility.IsLoginValid(mySite, usuario.Nombre ))
            {
                spItem["Asignado a"] = myWeb.AllUsers[usuario.Nombre];
                spItem["IDOriginal"] = incidente.IdIncidente;
                spItem.Update();
                resultado = true;            
            }

            myWeb.Close();
            mySite.Close();
            return resultado;
            
        }


        #endregion

        /// <summary>
        /// Dada una lista de sharepoint y una lista de datacampo 
        /// conteniendo nombre de los campos, tipo y un valor para los 
        /// mismos, se realiza el alta en sharepoint con la información. 
        /// Se usa tambien el sitio sharepoint para obtener información sobre
        /// la conversión de fechas del formato "dd-mm-aaaa hh:mm" a
        /// cualquier formato configurado en el sharepoint.
        /// Retorna ID y otra información de lo creado.
        /// </summary>
        /// <param name="myWeb"></param>
        /// <param name="spLista"></param>
        /// <param name="campos"></param>
        /// <returns>DataAltaIncidente</returns>
        public DataAltaIncidente Impactar(SPWeb myWeb, SPList spLista, List<DataCampo> campos)
        {
            SPListItem newItem = spLista.Items.Add();
            foreach (DataCampo dataCampo in campos)
            {
                switch (dataCampo.Tipo)
                {
                    case CampoSharepoint.DateTime:
                        string[] fechaHora = dataCampo.Valor.Split(' ');
                        newItem[dataCampo.Titulo] = SPUtility.ParseDate(myWeb, fechaHora[0], fechaHora[1], false);
                        break;
                    default:
                        newItem[dataCampo.Titulo] = dataCampo.Valor;
                        break;
                }
            }
            newItem.Update();
            return new DataAltaIncidente(newItem.ID.ToString(), spLista.DefaultViewUrl);
        }

































































        /*


        //ESTO ES UNA PRUEBA, NO HACE NADA!!!
        public bool Validar(SPList spLista, List<DataCampo> campos)
        {
            foreach (DataCampo dataCampo in campos)
            {
                SPField sField = spLista.Fields["dc.Titulo"];    
                switch (sField.TypeAsString)
                {
                    case "Text":
                        break;
                            
                    case "DateTime":
                        break;

                    case "Note":
                        break;

                    case "Choice": 
                        System.Collections.Specialized.StringCollection specialString = 
                            ((SPFieldChoice)spLista.Fields["dc.Titulo"]).Choices;
                        break;

                    case "User":
                        string user;
                        foreach ( SPPermission perm in spLista.Permissions){
                            user = perm.Xml;
                        }
          
                        oListItem["Assigned To"] = oWebsite.AllUsers["User_Name"];
                        oListItem.Update();
                        break;

                    default: 
                        throw new Exception("TIPO NO CONSIDERADO");
                        //break;
                }
                

                
            }
            return true;
        }







        

        
        
        
        public static string GetStringField(SPListItem item, string key)
        {
            if (item[key] != null)
            {
                return item[key].ToString();
            }
            return "";
        }

//Another common field type is the multi line text fields. These fields can store rich text or even html. Here are a couple of functions that will get the contents of the filed as HTML and as plain text.



        public static string GetMultiLineTextAsHTML(SPListItem item, string key)
        {

            SPFieldMultiLineText field = item.Fields[key] as SPFieldMultiLineText;
            if (field != null)
            {
                return field.GetFieldValueAsHtml(item[key]);
            }

            return "";
        }

        public static string GetMultiLineTextAsPlainText(SPListItem item, string key)
        {

            SPFieldMultiLineText field = item.Fields[key] as SPFieldMultiLineText;
            if (field != null)
            {
                return field.GetFieldValueAsText(item[key]);
            }

            return "";
        }

    One of the more powerful column types is People and Groups. 
    Getting the underlying SPUser, SPGroup or collection of SPUsers 
        and SPGroups can be challenging. 
        Check out these functions that make it easier.

        public static SPUser GetSPUser(SPListItem item, string key)
        {
            SPFieldUser field = item.Fields[key] as SPFieldUser;

            if (field != null)
            {
                SPFieldUserValue fieldValue = field.GetFieldValue(item[key].ToString()) as SPFieldUserValue;
                if (fieldValue != null)
                {
                    return fieldValue.User;
                }
            }
            return null;
        }

        public static SPGroup GetSPGroup(SPListItem item, string key)
        {
            SPFieldUser field = item.Fields[key] as SPFieldUser;
            if (field != null)
            {
                SPFieldUserValue fieldValue = field.GetFieldValue(item[key].ToString()) as SPFieldUserValue;
                if (fieldValue != null)
                {
                    string groupName = fieldValue.LookupValue;
                    return item.Web.SiteGroups[groupName];
                }
            }
            return null;
        }


        public static List<SPUser> GetSPUserCollection(SPListItem item, string key)
        {
            SPFieldUserValueCollection fieldValues = item[key] as SPFieldUserValueCollection;
            if (fieldValues != null)
            {
                List<SPUser> users = new List<SPUser>();
                foreach (SPFieldUserValue value in fieldValues)
                {
                    users.Add(value.User);
                }
                return users;
            }

            return null;
        }


        public static string GetItemAttachmentUrl(SPListItem item)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(SPEncode.UrlEncodeAsUrl(item.Web.Url));
            sb.Append(@"/");
            sb.Append(SPEncode.UrlEncodeAsUrl(item.ParentList.RootFolder.Url));
            sb.Append(@"/");
            sb.Append(item.File.Name);
            return sb.ToString();
        }



        public static SPListItem GetListItemFromLookup(SPListItem item, string lookupTableName, string key)
        {
            SPFieldLookup field = item.Fields[key] as SPFieldLookup;
            if (field != null)
            {
                SPFieldLookupValue fieldValue = field.GetFieldValue(item[key].ToString()) as SPFieldLookupValue;
                if (fieldValue != null)
                {
                    return item.Web.Lists[lookupTableName].GetItemById(fieldValue.LookupId);
                }
            }
            return null;
        }









        /*
        public List<DataLista> ObtenerListas()
        {
            SPSite mySite = new SPSite(ConfigurationManager.AppSettings.Get("topSPSite") + "infocorp");
            SPWeb myWeb = mySite.OpenWeb();
            List<DataLista> listas = new List<DataLista>();

            foreach (SPList spLista in myWeb.Lists)
            {
                DataLista lista = new DataLista(spLista.Title, spLista.ID);
                listas.Add(lista);
            }
            myWeb.Close();
            mySite.Close();
            return listas;
        }


        public List<DataCampo> ObtenerCamposLista(Guid guidLista)
        {
            try{
                SPSite mySite = new SPSite(ConfigurationManager.AppSettings.Get("topSPSite") + "infocorp");
                SPWeb myWeb = mySite.OpenWeb();
                SPList spLista = myWeb.Lists.GetList(guidLista, true);

                List<DataCampo> campos = new List<DataCampo>();
                foreach (SPField spCampo in spLista.Fields)
                {
                    DataCampo campo = new DataCampo(spCampo.InternalName, spCampo.TypeAsString, spCampo.Title, "");
                    campos.Add(campo);
                }
                myWeb.Close();
                mySite.Close();
                return campos;
            }
            catch {}
            return null;
        }

        public bool Impactar(string urlSitio, Guid guidLista, List<DataCampo> campos)
        {
            SPSite mySite = new SPSite(urlSitio);
            SPWeb myWeb = mySite.OpenWeb();
            SPList spLista = myWeb.Lists.GetList(guidLista, true);
            SPListItem newItem = spLista.Items.Add();
            
            foreach (DataCampo dc in campos)
            {
                if (dc.Tipo == "Text" || dc.Tipo == "Note" ) newItem[dc.Titulo] = dc.Valor;
            }
            newItem.Update();
            return true;
        }
        
         */
    
        /// <summary>
        /// Mapea los tipos de campos de sharepoint a los de MGI
        /// </summary>
        /// <param name="spType">String representando el tipo de datos de sharepoint</param>
        /// <returns></returns>
        public static CampoSharepoint spTypeToCampoSharepoint(string spType)
        {
            switch (spType)
            {
                case "Choice":
                    return CampoSharepoint.Choice;
                case "DateTime":
                    return CampoSharepoint.DateTime;
                case "Number":
                    return CampoSharepoint.Number;
                case "Text":
                    return CampoSharepoint.Text;
                case "Boolean":
                    return CampoSharepoint.Boolean;
                case "Note":
                        return CampoSharepoint.Note;
                default:
                    throw new NotImplementedException();
            }
        }

    }
}
